﻿//==============================================================================================
//Author: Uncle Song
//Create Date: 2022-00-00
//Description: 对象池
//----------------------------------------------------------------------------------------------
//Alter History:
//              2010-08-03  add Codes.
//============================================================================================== 
using System;
using System.Collections.Generic;

namespace FrameWorkSong
{

    public interface IPool<T>
    {
        T Allocate();
        bool Recycle(T obj);
    }
    public interface IObjectFactory<T>
    {
        T Create();
    }
    /// <summary>
    /// 创建工厂类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class CustomObjectFactroy<T> : IObjectFactory<T>
    {
        protected Func<T> mFactoryMethod;
        //创建方法委托（用户提供）
        public  CustomObjectFactroy(Func<T> factoryMethod)
        {
            mFactoryMethod = factoryMethod;
        }
        //使用创建方法
        public T Create()
        {
            return mFactoryMethod();
        }
    }
    /// <summary>
    /// 对象池类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class Pool<T> : IPool<T>
    {
        //对象池
        protected Stack<T> mCachedStack = new Stack<T>();
        //创建工厂
        protected IObjectFactory<T> mFactory;
        //提取实例
        public T Allocate()
        {
            if (mCachedStack.Count>0)
            {
              return  mCachedStack.Pop();
            }
            else
            {
               return mFactory.Create(); 
            }
        }
        //缓存实例
        public abstract bool Recycle(T obj);
        //缓存数量
        public int CurCount
        {
            get { return mCachedStack.Count; }
        }
    }
    public class SimpleObjectPool<T> : Pool<T>
    {
        readonly Action<T> mResetMethod;
        /// <summary>
        /// 创建构造对象池
        /// </summary>
        /// <param name="factoryMethod">创建实例方法</param>
        /// <param name="resetMethod">对象重置时调用</param>
        /// <param name="initCount">预创建</param>
        public SimpleObjectPool(Func<T> factoryMethod, Action<T> resetMethod = null, int initCount = 0)
        {
            mFactory = new CustomObjectFactroy<T>(factoryMethod);
            mResetMethod = resetMethod;
            for (int i = 0; i < initCount; i++)
            {
                mCachedStack.Push(mFactory.Create());
            }
        }
        /// <summary>
        /// 重置缓存
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Recycle(T obj)
        {
            if (mResetMethod!=null)
            {
                mResetMethod(obj);
            }
            mCachedStack.Push(obj);
            return true;
        }
    }
}
